# -*- coding:utf-8 -*-
# __author__ : "徐川东"
# Date: 2020/9/10 13:54
# File: apidecorator.py
# IDE: PyCharm

from functools import wraps

from coreapi import exceptions

from utils import common
from Apps.Dictionary import models
import datetime
from Apps.Toad import models as t_models
from django.contrib.auth.models import AnonymousUser
from rest_framework.request import Request
from django.http import HttpRequest
from utils.response.response import BaseJsonResponse
from utils.response import httpstate
import json
from datetime import date
import datetime
from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from itsdangerous import TimedJSONWebSignatureSerializer as Jwt
from django.conf import settings


# 时间格式化类
class CJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj, date):
            return obj.strftime('%Y-%m-%d')
        else:
            return json.JSONEncoder.default(self, obj)


class ApiDecorator(object):
    def __call__(self, func):
        @wraps(func)
        def wrapped_function(view, *args, **kwargs):

            if len(args) <= 0:
                return func(view, *args, **kwargs)
            request = args[0]

            if not isinstance(request, Request) and not isinstance(request, HttpRequest):
                return func(view, *args, **kwargs)

            if request.META.get('HTTP_X_FORWARDED_FOR'):
                ip = request.META.get("HTTP_X_FORWARDED_FOR")
            else:
                ip = request.META.get("REMOTE_ADDR")

            url = f"http://{request.get_host()}{request.get_full_path()}"
            token_data = request.GET

            # 从头部获取token
            token = request.META.get('HTTP_TOKEN')

            if not token:
                token = request.META.get('HTTP_AUTHORIZATION')
                if token:
                    token = token.split(' ')[-1]
            print(token)
            if not token:
                raise exceptions.AuthenticationFailed('认证失败,token不能为空')
            # token解码，生成对应的用户信息
            serializer = Jwt(settings.SECRET_KEY, settings.TOKEN_OUT_TIME)
            try:
                user = serializer.loads(token)
                request.user = user
            except Exception as ex:
                raise exceptions.AuthenticationFailed('认证失败,token格式不正确')

            try:
                dictionary = models.StDictionary.objects.filter(id=view.dictionary.id).first()
                if dictionary.status == 0:
                    return BaseJsonResponse(code=httpstate.CODE_NOT_FOUND_ERROR, message=httpstate.CODE_NOT_FOUND_ERROR)
            except Exception as e:
                print(e)
            array_url = request.get_full_path().split('/')
            action = array_url[len(array_url)-2]

            api = models.StApi.objects.filter(dictionary=view.dictionary, function=action).first()

            if not api:
                api = models.StApi.objects.filter(dictionary=view.dictionary).first()
            requires = ""
            if api.type == 'post':
                requires = json.dumps(request.data)
            else:
                requires = json.dumps(request.GET)
            flag = True
            # 执行方法
            try:
                result = func(view, *args, **kwargs)
                api_log = models.StApiLog(
                    result=1,
                    dictionary=view.dictionary.id,
                    token=token,
                    requires=requires,
                    message="",
                    api=api,
                    logtime=datetime.datetime.now(),
                )
                api_log.save()
                page = result.data.get('page')
                return_data = result.data['data']
                if page:
                    return_data['page'] = page
                return BaseJsonResponse(data=return_data)
            except Exception as e:
                api_log = models.StApiLog(
                    dictionary=view.dictionary.id,
                    token=token,
                    requires=requires,
                    result=0,
                    message=str(e),
                    api=api,
                    logtime=datetime.datetime.now(),
                )
                api_log.save()
                return BaseJsonResponse(code=httpstate.CODE_PARAMETER_ERROR, message=httpstate.MSG_PARAMETER_ERROR)
        return wrapped_function
